#include "aky_com_include.h"


void aky_bat_init(void)
{
	LBTM= 0x61;								//01100001		out LBT input p11 is ground p10 is LBT input	
}


//返回低电压检测adc直接值
uint16_t get_bat_row_val(void) 
{
    uint16_t res = 0;
	res = (ADCDH << 8) | ADCDM;
    res >>= 4; //转换成 12bit 
    return res;
}



//通过r4 r5反推算得出当前电压值 如3.4v 则返回 340
uint16_t get_cur_bat_val_by_math(void)
{
    volatile uint32_t VoltageValue;
    uint16_t res = 0;

    VoltageValue = get_bat_row_val();
	VoltageValue = (VoltageValue * SARADC_REFV * (R4+R5));
	VoltageValue =	(VoltageValue / (SARADC_FULLRANGE*R5));
	VoltageValue += V_OFFSET;

    res = VoltageValue;
    return res;
}

uint16_t check_low_bat_buf[CHECK_LIMIT] = {0};
uint16_t check_low_bat_cnt = 0;
uint16_t cur_bat_val = 0;
uint16_t check_low_bat_compare_cnt = 0;
//检测低电前的必要初始化
void check_low_bat_init(void)
{
    check_low_bat_cnt = 0;
    check_low_bat_compare_cnt = 0;
}

//比较器方式 是否触发低电压  不阻塞 可以在开始测量后调用
//return \1 触发低电压
uint8_t check_low_bat_trig_compare(void)
{
    uint8_t res = 0;
    if((LBTM&0x02)==0x02) 				
    {
    	check_low_bat_compare_cnt++;
    	if(check_low_bat_compare_cnt>=CHECK_LIMIT)
    	{
    		check_low_bat_compare_cnt=CHECK_LIMIT;
            res = 1;
    	}
    }
    else													
    {
    	check_low_bat_compare_cnt=0;
    }

    return res;
}

//adc方式或比较器方式检测是否触发低电压  不阻塞 但adc方式会与传感器adc冲突 不能在需要压力检测的界面调用
//low_bat_threshold 低电压的阈值
//return \1 触发低电压
uint8_t check_low_bat_trig(uint16_t low_bat_threshold)
{
    uint8_t res = 0;
    uint8_t i = 0;
    uint32_t sum = 0;
    #if (ADC_DETEC_BAT_ENABLE == 1)
    for (i = 0; i < (CHECK_LIMIT - 1); i++)//将低地址数据往高处移动1
    {
        check_low_bat_buf[(CHECK_LIMIT-1)-i] = check_low_bat_buf[(CHECK_LIMIT-2)-i];
    }

    check_low_bat_buf[0] = get_cur_bat_val_by_math();//最新的数据放到最低地址

    check_low_bat_cnt++;
    if (check_low_bat_cnt >= CHECK_LIMIT)
    {
        check_low_bat_cnt = CHECK_LIMIT;
        for (i =  0; i < (CHECK_LIMIT); i++)//得出相加值
        {
            sum += check_low_bat_buf[i];
        }
        sum /= CHECK_LIMIT;
        cur_bat_val = sum;
        if (sum < low_bat_threshold)
        {
            res = 1;
        }
    }
    #endif
    if (res == 0)
    {
        res = check_low_bat_trig_compare();
    }
    low_bat_threshold = 0; //无作用 为了不使能adc检测时编译器不报警告

    return res;
}

//切换到低电压检测adc通道
void aky_adc_bat_init(void)
{
	AMPM = 0x23;						//Disable GX Buf + PGIA chopper clock = 7.8kHz(/32) + PGIA Gain = x1 + Enable PGIA Chopper & PGIA 	
	ADCM1= 0x76;	// adc ref = 0.5 * avddr
	VREG = 0x9d;	//2.7v avddr
	ADCM2= 0x12;						//ADC Clock = 250kHz + OSR = 1953(2k)Hz(250k/128) + DRDY flag clear
	CHS	 = 0x2c;						//AI3 VSS	
	OPM	 = 0x00;						//00000001 Disable OPA function for Constant current. no bias function.
	ADCM1 |= 0x01;					//Enable ADC	
}

 //切换回传感器adc通道
void aky_adc_bat_deinit(void)
{
    aky_sdadc_init();
}


//低电压检测 会阻塞一段时间 不要在开始测量后调用
//low_bat_threshold 低电压的阈值
//return 返回1则触发低电压
uint8_t check_low_bat_pro(uint16_t low_bat_threshold)
{
    uint16_t time_out = 0;
    uint16_t fil_cnt = 0;
    uint16_t fil_cnt1 = 0;
    uint8_t res = 0;
    #if (ADC_DETEC_BAT_ENABLE == 1)
    aky_adc_bat_init();//切换到低电压检测adc通道
    check_low_bat_init();
    aky_tick_delay_ms(50);
    while (1)
    {
        time_out++;
        if (time_out > 1000)
        {
            goto low_bat_exit;
        }
        
        if (check_low_bat_trig(low_bat_threshold) == 1)
        {
            fil_cnt++;
            fil_cnt1 = 0;
            if (fil_cnt > 5) //低电压触发
            {
                fil_cnt = 0;
                res = 1;
                goto low_bat_exit;
            }
        }
        else
        {
            fil_cnt = 0;
            fil_cnt1++;
            if (fil_cnt1 > (CHECK_LIMIT * 2))
            {
                fil_cnt1 = 0;
                goto low_bat_exit;
            }
        }
    }
    #endif

    check_low_bat_init();
    aky_tick_delay_ms(50);
    while (1)
    {
        time_out++;
        if (time_out > 1000)
        {
            goto low_bat_exit;
        }
        
        if (check_low_bat_trig_compare() == 1)
        {
            fil_cnt++;
            fil_cnt1 = 0;
            if (fil_cnt > 5) //低电压触发
            {
                fil_cnt = 0;
                res = 1;
                goto low_bat_exit;
            }
        }
        else
        {
            fil_cnt = 0;
            fil_cnt1++;
            if (fil_cnt1 > (CHECK_LIMIT * 2))
            {
                fil_cnt1 = 0;
                goto low_bat_exit;
            }
        }
    }


low_bat_exit:
    AKY_ASM_NOP();
    #if (ADC_DETEC_BAT_ENABLE == 1)
    aky_adc_bat_deinit(); //切换回传感器adc
    #else
    low_bat_threshold = 0;//无作用 为了不使能adc检测时编译器不报警告
    #endif
    return res;
}

e_charge_stat_t g_e_charge_stat = NO_CHARGE;
//获取当前检测到的充电状态
e_charge_stat_t get_cur_charge_stat(void)
{
    return g_e_charge_stat;
}

#define CHARGE_DETECT_FIL_LIMIT (10ul) //充电检测滤波次数

//充电状态检测处理 在中断调用
void charge_stat_detect_pro(void)
{
    static uint16_t fil_cnt = 0;
    static uint16_t fil_cnt1 = 0;
    static uint16_t fil_cnt2 = 0;
    static uint8_t last_full_stat = 0;//记住上一次电平
    static uint8_t last_charge_stat = 0;
    static uint16_t const_fil_cnt = 0;//电平稳定状态滤波判断
    
    if (last_full_stat != FULL)
    {
        last_full_stat = FULL;
        const_fil_cnt = 0;
    }

    if (last_charge_stat != CHARGE)
    {
        last_charge_stat = CHARGE;
        const_fil_cnt = 0;
    }

    const_fil_cnt++;
    if (const_fil_cnt < CHARGE_DETECT_FIL_LIMIT * 2)
    {
        //稳定滤波  一段时间电平稳定后才判断其它状态 否则为一直翻转不稳定 没锂电但usb接入状态
        g_e_charge_stat = NO_BAT_AND_USB_INPUT;
    }
    else if (const_fil_cnt >= CHARGE_DETECT_FIL_LIMIT * 2)
    {
        //冗余 给一个最大值 预防溢出  
        const_fil_cnt = CHARGE_DETECT_FIL_LIMIT * 2;
        if (FULL == 1 && CHARGE == 1)
        {
            //两个引脚都为高电平则是空闲未充电状态
            fil_cnt++;
            fil_cnt1 = 0;
            fil_cnt2 = 0;
            if (fil_cnt > CHARGE_DETECT_FIL_LIMIT)
            {
                fil_cnt = 0;
                g_e_charge_stat = NO_CHARGE;
            }
        }
        else if (FULL == 0 || CHARGE == 0)
        {
            if (FULL == 0 && CHARGE == 1)
            {
                //full拉低 charge高电平则充满
                fil_cnt = 0;
                fil_cnt1++;
                fil_cnt2 = 0;
                if (fil_cnt1 > CHARGE_DETECT_FIL_LIMIT)
                {
                    fil_cnt1 = 0;
                    g_e_charge_stat = FULL_BAT;
                }
            }
            else if (FULL == 1 && CHARGE == 0)
            {
                //full高电平 charge拉低则正在充电
                fil_cnt = 0;
                fil_cnt1 = 0;
                fil_cnt2++;
                if (fil_cnt2 > CHARGE_DETECT_FIL_LIMIT)
                {
                    fil_cnt2 = 0;
                    g_e_charge_stat = CHARGING;
                }
            }
        }
    }
}


code uint16  bat_val_table[] = {340, 375 , 410 ,0xffff};//最大 - 最小 / (格数 - 1) =  每格电压
uint8 get_baterry_cells(uint16 bat_val)
{
    uint8 bat_val_table_size = 0;
    uint8 res = 0;
    uint8 i;
    bat_val_table_size = sizeof(bat_val_table)/sizeof(bat_val_table[0]);

    for (i = 0; i < bat_val_table_size; i++)
    {
        if (bat_val < bat_val_table[i])
        {
            res += i;
            goto BAT_EXIT;
        }
    }
BAT_EXIT:
    return res;
}
void low_bat_icon_on(void)
{
    //电池框

	OLED_DrawRectangle(20, 20, 80, 40, OLED_FILLED);
    OLED_ClearArea(22,22,76,36);
	OLED_DrawRectangle(100, 33 , 5, 15, OLED_FILLED);
} 
//显示电池格数
//cells 需要显示的格数
void show_baterry_cells(uint8 cells)
{
	low_bat_icon_on();
    switch (cells)
    {
    case 3:
    	OLED_DrawRectangle(68, 24 , 20, 32, OLED_FILLED);
    case 2:
    	OLED_DrawRectangle(46, 24 , 20, 32, OLED_FILLED);
    case 1:
    	OLED_DrawRectangle(24, 24 , 20, 32, OLED_FILLED);
        break;

    default:
        break;
    }
}
